#pragma once
#pragma comment( lib, "Wininet.lib" )

#include <windows.h>
#include <Wininet.h>

#include "STLUtil.h"
#include "FileSystemUtil.h"

#ifndef UNIX_PATH_DELIMITER
	#define UNIX_PATH_DELIMITER			_T( "/" )
#endif

#define SET_LAST_ERROR_AND_RETURN_FALSE	{	this->m_dwLastError = ::GetLastError();	\
											return FALSE; }

#define DEFAULT_RETRY_COUNT			( 3 )

#define DEFAULT_READ_BUFFER_SIZE	( 1024 )

class CHTTPMgr
{
	public :

		typedef struct _HTTPFile{
			tstring			strServer;
			tstring			strObject;
			INTERNET_PORT	nPort;
			HINTERNET		hConnection;
			HINTERNET		hFile;

			_HTTPFile( void ) :
				hConnection(	NULL ),
				hFile(			NULL ){
			}

			_HTTPFile( LPCTSTR pszURL ) :
				hConnection(	NULL ),
				hFile(			NULL ){
				this->ParseURL( pszURL );
			}

			~_HTTPFile( void ){
				this->CleanUp();
			}

			void CleanUp( void ){
				if( hConnection )
				{
					::InternetCloseHandle( this->hConnection );
					this->hConnection = NULL;
				}
				if( hFile )
				{
					::InternetCloseHandle( this->hFile );
					this->hFile = NULL;
				}
			}

			BOOL ParseURL( LPCTSTR pszURL ){
				return ParseURL( pszURL, this->strServer, this->strObject, this->nPort );
			}
			
			static BOOL ParseURL( LPCTSTR pszURL, tstring &strServer, tstring &strObject, INTERNET_PORT &nPort ){	// LIKE AfxParseURL
				if( !pszURL ||
					!_tcslen( pszURL ) )
					return FALSE;

				tstring sURL;
				if( !_tcsncmp( pszURL, _T( "http://" ), 7 ) )
					sURL.assign( pszURL + 7 );
				else
					sURL.assign( pszURL );

				strServer.clear();
				strObject.clear();
				nPort = INTERNET_DEFAULT_HTTP_PORT;

				tstring::size_type nOffSet = sURL.rfind( _T( ":" ) );
				if( tstring::npos != nOffSet )
				{
					nPort = _tstoi( sURL.substr( nOffSet + 1 ).c_str() );
					sURL.erase( nOffSet );
				}

				nOffSet = sURL.find( UNIX_PATH_DELIMITER );
				if( tstring::npos == nOffSet )
					strServer = sURL;
				else
				{
					strServer = sURL.substr( 0, nOffSet );
					strObject = sURL.substr( nOffSet );
				}

				return TRUE;
			}

			

		} HTTPFile;

					CHTTPMgr( void );
		virtual		~CHTTPMgr( void );

		BOOL		ReadWebPage( LPCTSTR pszURL, tstring &sWebPageContent, UINT nReTryCount = DEFAULT_RETRY_COUNT );

		BOOL		DownLoad( LPCTSTR pszURL, LPCTSTR pszNew, BOOL bCreatePath = TRUE, UINT nReTryCount = DEFAULT_RETRY_COUNT );

		BOOL		GetHttpStatus( LPCTSTR pszURL, LONG &lStatus );

		DWORD		GetLastError( void );

	private :

		BOOL		GetHttpStatus( HTTPFile &httpFile, LONG &lStatus );

		BOOL		_ReadWebPage( LPCTSTR pszURL, tstring &sWebPageContent );

		BOOL		_DownLoad( LPCTSTR pszURL, LPCTSTR pszNew );

		BOOL		GetFileSize( const HANDLE hFile, DWORD &dwFileSize );
		
		HINTERNET	m_hInternetSession;

		DWORD		m_dwLastError;
};
